package com.lmmob.autotest.uitest.controls;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.remote.ScreenshotException;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;

import javax.annotation.Nullable;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

public abstract class Control {
    protected WebDriver webDriver;

    private Control parent;

    protected void setParent(Control parent) {
        this.parent = parent;
    }

    protected Control getParent() {
        return this.parent;
    }

    public Control(WebDriver webDriver) {
        this.webDriver = webDriver;
    }

    public final String getQuery() {
        if (parent != null) {
            return this.parent.getQuery() + getSelfQuery();
        } else {
            return "Ext.ComponentQuery" + getSelfQuery();
        }
    }

    protected String getSelfQuery() {
        return StringUtils.EMPTY;
    }

    protected abstract String getName();

    public void show() {
    }

    public boolean isReadOnly() {
        return false;
    }

    public String getId() {
        String script = "return " + this.getQuery() + ".id";
        return (String) runScript(script);
    }

    protected Object runScript(String script) {
        JavascriptExecutor executor = (JavascriptExecutor) webDriver;
        return executor.executeScript(script);
    }

    protected WebElement findElement(final By by) {
        WebDriverWait wait = new WebDriverWait(webDriver, 8);
        try {
            WebElement element = wait.until(new ExpectedCondition<WebElement>() {
                public WebElement apply(@Nullable WebDriver webDriver) {
                    return webDriver.findElement(by);
                }
            });
            return element;
        } catch (WebDriverException e) {
            saveSnapshot(e);
            return null;
        }
    }

    private void saveSnapshot(WebDriverException e) {
        try {
            String snapshotInBase64 = extractScreenShot(e);
            FileOutputStream stringOutputStream = new FileOutputStream("snapshot.htm");
            IOUtils.write(getSnapshot(snapshotInBase64), stringOutputStream, "UTF-8");
        } catch (IOException e1) {

        }
    }

    private String getSnapshot(String snapshotInBase64) {
        return String.format("<img src=\"data:image/gif;base64,%s\" />", snapshotInBase64);
    }

    public String extractScreenShot(WebDriverException e) {
        Throwable cause = e.getCause();
        if (cause instanceof ScreenshotException) {
            return ((ScreenshotException) cause).getBase64EncodedScreenshot();
        }
        return null;
    }

    protected void waitAWhile(long period, TimeUnit unit) {
        try {
            unit.sleep(period);
        } catch (InterruptedException e) {

        }
    }

}
